import React, { useState, useEffect, useMemo } from 'react';
import classnames from 'classnames';
import { getComponentRotatedStyle } from '@utils/style'
import { setComponent } from '@/store/actions/visualdrag';

export default (props) => {
  const { curComponent, componentData, marklineFlag, curComponentIndex, dispatch } = props;
  const lines = useMemo(() => ['xt', 'xc', 'xb', 'yl', 'yc', 'yr'], []); // 分别对应三条横线和三条竖线
  const diff = 10; // 相距 dff 像素将自动吸附
  const [lineStatus, setlineStatus] = useState({
    xt: false,
    xc: false,
    xb: false,
    yl: false,
    yc: false,
    yr: false,
  });

  // 隐藏标线
  const hideLine = () => {
    let res = { ...lineStatus }
    Object.keys(res).forEach(line => {
      res[line] = false
    })
    setlineStatus(res);
  }
  // 获取dom元素
  const getDomNode = (id) => {
    return document.getElementById(id);
  }
  // 展示标线
  const showLine = (isDownward, isRightward) => {
    const linesNodeObj = {};
    lines.map(mm => {
      linesNodeObj[mm] = getDomNode(`line${mm}`)
    });
    const components = componentData
    const curComponentStyle = getComponentRotatedStyle(curComponent.style)
    const curComponentHalfwidth = curComponentStyle.width / 2
    const curComponentHalfHeight = curComponentStyle.height / 2

    hideLine()
    components.forEach(component => {
      if (component == curComponent) return
      const componentStyle = getComponentRotatedStyle(component.style)
      const { top, left, bottom, right } = componentStyle
      const componentHalfwidth = componentStyle.width / 2
      const componentHalfHeight = componentStyle.height / 2

      const conditions = {
        top: [
          {
            isNearly: isNearly(curComponentStyle.top, top),
            lineNode: linesNodeObj.xt, // xt
            line: 'xt',
            dragShift: top,
            lineShift: top,
          },
          {
            isNearly: isNearly(curComponentStyle.bottom, top),
            lineNode: linesNodeObj.xt, // xt
            line: 'xt',
            dragShift: top - curComponentStyle.height,
            lineShift: top,
          },
          {
            // 组件与拖拽节点的中间是否对齐
            isNearly: isNearly(curComponentStyle.top + curComponentHalfHeight, top + componentHalfHeight),
            lineNode: linesNodeObj.xc, // xc
            line: 'xc',
            dragShift: top + componentHalfHeight - curComponentHalfHeight,
            lineShift: top + componentHalfHeight,
          },
          {
            isNearly: isNearly(curComponentStyle.top, bottom),
            lineNode: linesNodeObj.xb, // xb
            line: 'xb',
            dragShift: bottom,
            lineShift: bottom,
          },
          {
            isNearly: isNearly(curComponentStyle.bottom, bottom),
            lineNode: linesNodeObj.xb, // xb
            line: 'xb',
            dragShift: bottom - curComponentStyle.height,
            lineShift: bottom,
          },
        ],
        left: [
          {
            isNearly: isNearly(curComponentStyle.left, left),
            lineNode: linesNodeObj.yl, // yl
            line: 'yl',
            dragShift: left,
            lineShift: left,
          },
          {
            isNearly: isNearly(curComponentStyle.right, left),
            lineNode: linesNodeObj.yl, // yl
            line: 'yl',
            dragShift: left - curComponentStyle.width,
            lineShift: left,
          },
          {
            // 组件与拖拽节点的中间是否对齐
            isNearly: isNearly(curComponentStyle.left + curComponentHalfwidth, left + componentHalfwidth),
            lineNode: linesNodeObj.yc, // yc
            line: 'yc',
            dragShift: left + componentHalfwidth - curComponentHalfwidth,
            lineShift: left + componentHalfwidth,
          },
          {
            isNearly: isNearly(curComponentStyle.left, right),
            lineNode: linesNodeObj.yr, // yr
            line: 'yr',
            dragShift: right,
            lineShift: right,
          },
          {
            isNearly: isNearly(curComponentStyle.right, right),
            lineNode: linesNodeObj.yr, // yr
            line: 'yr',
            dragShift: right - curComponentStyle.width,
            lineShift: right,
          },
        ],
      }

      const needToShow = []
      const { rotate } = curComponent.style
      Object.keys(conditions).forEach(key => {
        // 遍历符合的条件并处理
        conditions[key].forEach((condition) => {
          if (!condition.isNearly) return;
          // 修改当前组件样式
          let value = rotate != 0 ? translatecurComponentShift(key, condition, curComponentStyle) : condition.dragShift;
          let data = [...componentData];
          data.map(mm => {
            if (mm.id == curComponentIndex) {
              mm.style[key] = value;
            }
          })
          dispatch(setComponent(data));

          condition.lineNode.style[key] = `${condition.lineShift}px`
          needToShow.push(condition.line)
        })
      })

      // 同一方向上同时显示三条线可能不太美观，因此才有了这个解决方案
      // 同一方向上的线只显示一条，例如多条横条只显示一条横线
      if (needToShow.length) {
        chooseTheTureLine(needToShow, isDownward, isRightward)
      }
    })
  }

  const translatecurComponentShift = (key, condition, curComponentStyle) => {
    const { width, height } = curComponent.style
    if (key == 'top') {
      return Math.round(condition.dragShift - (height - curComponentStyle.height) / 2)
    }

    return Math.round(condition.dragShift - (width - curComponentStyle.width) / 2)
  }

  // 各方向标线是否展示
  const chooseTheTureLine = (needToShow, isDownward, isRightward) => {
    // 如果鼠标向右移动 则按从右到左的顺序显示竖线 否则按相反顺序显示
    // 如果鼠标向下移动 则按从下到上的顺序显示横线 否则按相反顺序显示
    let res = {
      xt: false,
      xc: false,
      xb: false,
      yl: false,
      yc: false,
      yr: false,
    };
    if (isRightward) {
      if (needToShow.includes('yr')) {
        res.yr = true
      } else if (needToShow.includes('yc')) {
        res.yc = true
      } else if (needToShow.includes('yl')) {
        res.yl = true
      }
    } else {
      // eslint-disable-next-line no-lonely-if
      if (needToShow.includes('yl')) {
        res.yl = true
      } else if (needToShow.includes('yc')) {
        res.yc = true
      } else if (needToShow.includes('yr')) {
        res.yr = true
      }
    }

    if (isDownward) {
      if (needToShow.includes('xb')) {
        res.xb = true
      } else if (needToShow.includes('xc')) {
        res.xc = true
      } else if (needToShow.includes('xt')) {
        res.xt = true
      }
    } else {
      // eslint-disable-next-line no-lonely-if
      if (needToShow.includes('xt')) {
        res.xt = true
      } else if (needToShow.includes('xc')) {
        res.xc = true
      } else if (needToShow.includes('xb')) {
        res.xb = true
      }
    }

    setlineStatus(res)
  }

  // 判断俩组件是否接近
  const isNearly = (dragValue, targetValue) => {
    return Math.abs(dragValue - targetValue) <= diff
  }

  useEffect(() => {
    if (marklineFlag.index != 0) {
      showLine(marklineFlag.data.isDownward, marklineFlag.data.isRightward)
    } else {
      hideLine()
    }
  }, [marklineFlag])

  return (
    <div className="mark-line">
      {
        lines.map((line, idx) => {
          return (
            <div key={idx}
              className={classnames({
                line: true,
                xline: line.includes('x'),
                yline: !line.includes('x')
              })}
              style={{ visibility: lineStatus[line] ? 'visible' : 'hidden' }}
              id={`line${line}`}
            ></div>
          )
        })
      }
    </div >
  );
}

